﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.IO;

namespace NexTrackDesktop.Media
{
    /// <summary>
    /// This class holds all song library related info and events.
    /// </summary>
    public class Library
    {
        private List<Song> _library;
        private HashSet<Uri> _fileUris; // file locations

        public ITagger Tagger { get; set; }
        public ReadOnlyCollection<Song> Items
        {
            get
            {
                return new ReadOnlyCollection<Song>(_library);
            }
        }

        /// <summary>
        ///     Creates an empty library with the given file tagger to be used for tagging songs.
        /// </summary>
        /// <param name="tagger">
        ///     Optional. The tagger to use for collecting song tags from input files.
        ///     If tagger is null or missing, some sort of default tagger will be used.
        /// </param>
        public Library(ITagger tagger = null)
        {
            _fileUris = new HashSet<Uri>();
            _library = new List<Song>();

            if (tagger == null)
                tagger = new DiscogsArtTagger(new TagLibTagger());

            this.Tagger = tagger;
        }

        /// <summary>
        ///     Adds a song to the library from the given location uri. The song will be tagged
        ///     using this instance's Tagger
        /// </summary>
        /// <param name="uri"></param>
        public void AddFile(Uri uri)
        {
            if (_fileUris.Contains(uri))
                return;

            Song newSong = new Song() { Location = uri };
            Tagger.tag(newSong);

            _fileUris.Add(uri);
            _library.Add(newSong);

            if (SongAdded != null)
                SongAdded(newSong);
        }


        public static string[] searchExtensions = { ".mp3", ".mp4", ".m4a", ".ogg", ".flac", ".cda", ".wma" };
        /// <summary>
        /// This method is called recursivly to add folders within folders to library
        /// </summary>
        /// <param name="path">Path to folder</param>
        public void addFolderRecursive(string path)
        {
            foreach (var file in Directory.GetFiles(path))
            {
                if (searchExtensions.Contains(Path.GetExtension(file)))
                    AddFile(new Uri(file));
            }

            foreach (var folder in Directory.GetDirectories(path))
            {
                addFolderRecursive(folder);
            }
        }

        // Events triggered when the songs in the library are modified.        
        public event Action<Song> SongAdded;
        public event Action<Song> SongChanged; //TODO
        public event Action<Song> SongRemoved; //TODO
    }
}